package com.hgyc.mom.tool.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hgyc.mom.common.constant.CacheConstants;
import com.hgyc.mom.common.exception.BizException;
import com.hgyc.mom.common.print.*;
import com.hgyc.mom.common.redis.RedisCache;
import com.hgyc.mom.common.spring.SpringUtils;
import com.hgyc.mom.common.util.ObjectUtils;
import com.hgyc.mom.common.util.poi.ExcelUtil;
import com.hgyc.mom.system.entity.SysUser;
import com.hgyc.mom.system.service.SysUserService;
import com.hgyc.mom.tool.entity.AutoCodeRule;
import com.hgyc.mom.tool.entity.PrintTemplate;
import com.hgyc.mom.tool.entity.ToolLabelRecord;
import com.hgyc.mom.tool.mapper.PrintTemplateMapper;
import com.hgyc.mom.tool.service.AutoCodeRuleService;
import com.hgyc.mom.tool.service.PrintTemplateService;
import com.hgyc.mom.tool.service.ToolLabelRecordService;
import com.hgyc.mom.tool.vo.LabelRecordVO;
import com.hgyc.mom.tool.vo.PrintRequestVO;
import com.hgyc.mom.tool.vo.TemplateDataVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 标签打印模板Service业务层实现
 *
 * @author fwj
 * @since 2025-07-14
 */
@Slf4j
@Service
public class PrintTemplateServiceImpl extends ServiceImpl<PrintTemplateMapper, PrintTemplate> implements PrintTemplateService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AutoCodeRuleService autoCodeRuleService;

    @Autowired
    private ToolLabelRecordService toolLabelRecordService;

    @Autowired
    private SysUserService sysUserService;

    @Override
    public void saveTemplate(PrintTemplate printTemplate) {
        // TODO 其他逻辑
        save(printTemplate);
    }

    @Override
    public void updateTemplate(PrintTemplate printTemplate) {
        // TODO 其他逻辑
        updateById(printTemplate);
    }

    @Override
    public void removeTemplate(List<Long> ids) {
        // TODO 其他逻辑
        removeByIds(ids);
    }

    @Override
    public List<PrintTemplate> getMaterialTemplate(Long materialId) {
        LambdaQueryWrapper<PrintTemplate> qw = new LambdaQueryWrapper<>();
        qw.eq(PrintTemplate::getMaterialId, materialId);
        return list(qw);
    }

    @Override
    public TemplateDataVO design(Long id) {
        PrintTemplate printTemplate = baseMapper.selectById(id);
        List<PrintTemplateDataField> fieldList = redisCache.getCacheList(CacheConstants.PRINT_TEMPLATE_DATA_FIELD_CACHE_KEY + printTemplate.getDataSource(), PrintTemplateDataField.class);
        if (!CollectionUtils.isEmpty(fieldList)) {
            TemplateDataVO templateDataVO = new TemplateDataVO();
            List<String> hearderFieldList = fieldList.stream().map(PrintTemplateDataField::getFieldName).collect(Collectors.toList());
            // 获取数据
            String dataSource = printTemplate.getDataSource();
            PrintTemplateDataService printTemplateDataService = SpringUtils.getBean(dataSource+"DataService");
            List<Map<String, Object>> designData = printTemplateDataService.getDesignData();
            templateDataVO.setData(ExcelUtil.convertToCsv(hearderFieldList, designData));
            templateDataVO.setHash(printTemplate.getCheckSum());
            templateDataVO.setTemplate("/tool/print/template/download/" + printTemplate.getId());
            templateDataVO.setTitle(printTemplate.getName());
            if (Objects.equals(printTemplate.getType(), "barTender")) {
                templateDataVO.setType("btw");
            } else if (Objects.equals(printTemplate.getType(), "label")) {
                templateDataVO.setType("lpt");
            } else if (Objects.equals(printTemplate.getType(), "hiprint")) {
                templateDataVO.setType("hiprint");
            } else {
                templateDataVO.setType("btw");
            }
            return templateDataVO;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TemplateDataVO print(PrintRequestVO printRequestVO) {
        PrintTemplate printTemplate = baseMapper.selectById(printRequestVO.getTemplateId());
        List<PrintTemplateDataField> fieldList = redisCache.getCacheList(CacheConstants.PRINT_TEMPLATE_DATA_FIELD_CACHE_KEY + printTemplate.getDataSource(), PrintTemplateDataField.class);
        if (!CollectionUtils.isEmpty(fieldList)) {

            List<String> hearderFieldList = fieldList.stream().map(PrintTemplateDataField::getFieldName).collect(Collectors.toList());
            // 获取数据
            String dataSource = printTemplate.getDataSource();
            PrintTemplateDataService printTemplateDataService = SpringUtils.getBean(dataSource+"DataService");
            AutoCodeRule autoCodeRule = autoCodeRuleService.getById(printRequestVO.getRuleCodeId());
            List<Map<String, Object>> dataList = printTemplateDataService.getDataList(printRequestVO.getBizId(), printRequestVO.getParams(), autoCodeRule.getRuleCode(), printRequestVO.getPrintQty());

            // 生成打印记录
            List<LabelRecordVO> labelRecordList = new ArrayList<>();
            for (Map<String, Object> dataMap : dataList) {
                LabelRecordVO toolLabelRecord = new LabelRecordVO();
                toolLabelRecord.setMaterialId(ObjectUtils.toLong(dataMap.get("materialId")));
                toolLabelRecord.setMaterialCode(ObjectUtils.toString(dataMap.get("materialCode")));
                toolLabelRecord.setMaterialName(ObjectUtils.toString(dataMap.get("materialName")));
                toolLabelRecord.setMaterialSpec(ObjectUtils.toString(dataMap.get("materialSpec")));
                toolLabelRecord.setQty(ObjectUtils.toInt(dataMap.get("qty")));
                toolLabelRecord.setPrintTime(LocalDateTime.now());
                Long userId = ObjectUtils.toLong(StpUtil.getLoginId());
                SysUser currentUser = sysUserService.getById(userId);
                toolLabelRecord.setPrintUser(userId);
                toolLabelRecord.setPrintUserName(currentUser.getName());
                toolLabelRecord.setLabelCode(ObjectUtils.toString(dataMap.get("barcode")));

                toolLabelRecordService.save(toolLabelRecord);

                labelRecordList.add(toolLabelRecord);
            }

            TemplateDataVO templateDataVO = new TemplateDataVO();
            templateDataVO.setData(ExcelUtil.convertToCsv(hearderFieldList, dataList));
            templateDataVO.setHash(printTemplate.getCheckSum());
            templateDataVO.setTemplate("/tool/print/template/download/" + printTemplate.getId());
            templateDataVO.setTitle(printTemplate.getName());
            if (Objects.equals(printTemplate.getType(), "barTender")) {
                templateDataVO.setType("btw");
            } else if (Objects.equals(printTemplate.getType(), "label")) {
                templateDataVO.setType("lpt");
            } else if (Objects.equals(printTemplate.getType(), "hiprint")) {
                templateDataVO.setType("hiprint");
            } else {
                templateDataVO.setType("btw");
            }
            templateDataVO.setRecordList(labelRecordList);
            return templateDataVO;
        }
        return null;
    }

    @Override
    public List<PrintTemplateDataVO> getTemplateDataSource() {
        return redisCache.getCacheList(CacheConstants.PRINT_TEMPLATE_DATA_CACHE_KEY, PrintTemplateDataVO.class);
    }

    @Override
    public List<PrintElementType> getFieldByTemplate(Long templateId) {
        PrintTemplate printTemplate = getById(templateId);
        if (printTemplate != null && printTemplate.getDataSource() != null) {
            List<PrintTemplateDataField> fieldList = redisCache.getCacheList(CacheConstants.PRINT_TEMPLATE_DATA_FIELD_CACHE_KEY + printTemplate.getDataSource(), PrintTemplateDataField.class);
            return PrintElementConverter.convert(fieldList);
        }
        return null;
    }

    @Override
    public void saveHiPrint(PrintTemplate printTemplate) {
        if (printTemplate.getTemplateJson() == null) {
            throw new BizException("模板数据异常");
        }

        LambdaUpdateWrapper<PrintTemplate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(PrintTemplate::getTemplateJson, printTemplate.getTemplateJson());
        updateWrapper.eq(PrintTemplate::getId, printTemplate.getId());
        update(updateWrapper);
    }
}
